package grib2handler.grib.netcdf;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import grib2handler.util.FileUtil;

import ucar.ma2.Array;
import ucar.ma2.DataType;
import ucar.ma2.InvalidRangeException;
import ucar.ma2.Range;
import ucar.nc2.Attribute;
import ucar.nc2.Dimension;
import ucar.nc2.NetcdfFile;
import ucar.nc2.NetcdfFileWriteable;
import ucar.nc2.Structure;
import ucar.nc2.Variable;
import ucar.nc2.iosp.netcdf3.N3iosp;
/**
 * netcdf解压封装
 * @author charlie
 *
 */
public class NetcdfDump {
	private static NetcdfDump cdf = new NetcdfDump();
	private NetcdfDump() {
		
	}
	public static NetcdfDump getinstence() {
		return cdf;
	}
	public Map<String, String> dump(File file, String outPath) {
		Map<String, String> result = new HashMap<String, String>();
		NetcdfFile cdmf = null;
		try {
			cdmf = NetcdfFile.open(file.getAbsolutePath());
			List<Dimension> dims = cdmf.getDimensions();
			// System.out.println(cdmf.getDetailInfo());
			System.out.println("\n Dimensions: ");
			for (int i = 0; i < dims.size(); i++) {
				Dimension dim = dims.get(i);
				System.out.println(dim.getName() + " " + dim.getLength());
			}
			List<Variable> vars = cdmf.getVariables();
			System.out.println("\n Variables: ");
			for (int i = 0; i < vars.size(); i++) {
				Variable var = vars.get(i);

				System.out.println(var.getNameAndDimensions());
			}
			List<Attribute> atts = cdmf.getGlobalAttributes();
			for (int i = 0; i < atts.size(); i++) {
				Attribute att = atts.get(i);
				String name = att.getName().replace("/", "_");
				System.out.println(name);
			}
			
			for (int i = 0; i < vars.size(); i++) {
				Variable var = vars.get(i);
				String name = var.getName().replace("/", "_");
				System.out.println(var.getElementSize());
				System.out.println(var.getDescription());
				System.out.println(var.getDimensionsString());
				System.out.println(var.getNameAndDimensions());
				System.out.println(var.getShortName());
				System.out.println(var.getUnitsString());
				List<Range> ran = var.getRanges();
				System.out.println(ran);
				if (var.getDataType() == DataType.SEQUENCE) {
					Structure seq = (Structure) var;
					this.dumSequence(seq);
				} else {
//						List<Range> ranr = new ArrayList<Range>();
//						Range range1 = new Range(0, 0);
//						Range range2 = new Range(0, 0);
//						Range range3 = new Range(0, 180);
//						Range range4 = new Range(0, 359);
//						ranr.add(range1);
//						ranr.add(range2);
//						ranr.add(range3);
//						ranr.add(range4);
						Object obj = var.read();
//						Object obj = var.read(ranr);
						FileUtil.creatPath(outPath);
						FileUtil.write(outPath + "/" + var.getNameAndDimensions() + ".txt", obj.toString(), false);
						System.out.println();
						result.put(var.getNameAndDimensions(), obj.toString());
				}
			}
			System.out.println("end");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(cdmf != null) {
				try {
					cdmf.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return result;
	}

	public void dumSequence(Structure seq) throws IOException {
		Array[] arrays   = new Array[seq.getVariables().size()];	
		DataType[] types = new DataType[seq.getVariables().size()];	
		String[] names   = new String[seq.getVariables().size()];	
		List <Variable> seqVars = seq.getVariables();
		
		for (int i_seq=0;i_seq<seqVars.size();i_seq++) {
			Variable seqVar = seqVars.get(i_seq);
			String varName = N3iosp.makeValidNetcdfObjectName(seqVar
					.getShortName());
			names[i_seq] = seqVar.getShortName();
			List<Attribute> atts = seqVar.getAttributes();
			for (int i = 0; i < atts.size(); i++) {
				Attribute att = atts.get(i);
				String name = att.getName();
				System.out.println("-------" + name + " = "
						+ att.getStringValue());
			}	
			types[i_seq] = seqVar.getDataType();
			try {
				arrays[i_seq] = seqVar.read();
				System.out.println(arrays[i_seq]);
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			/**DataType dataType = seqVar.getDataType();
			if (dataType == DataType.SEQUENCE) {
				try {
					this.dumSequence((Structure) seqVar);
				} catch (IOException e) {
					e.printStackTrace();
				}
			} else {
				// System.out.println(varName);
			}**/
		}
		String line = "";
		for (int j=0;j<arrays.length;j++){
			line = line + names[j]+",";
		}
		System.out.println(line);
		for (int i=0;i< (arrays[0]).getSize();i++){
			line = "";
			for (int j=0;j<arrays.length;j++){				
				DataType type = types[j];
				if (type == DataType.STRING ||type == DataType.ENUM1||type == DataType.ENUM2 || type == DataType.ENUM4){
					line = line + arrays[j].getObject(i)+",";
				}else if (type == DataType.INT ||type == DataType.SHORT || type == DataType.BYTE){
					line = line + String.format("%d",arrays[j].getObject(i))+",";
				}else if (type == DataType.FLOAT || type == DataType.DOUBLE ){
					line = line + String.format("%f",arrays[j].getObject(i))+",";
				}else{
					line = line + arrays[j].getObject(i)+" ,";					
				}				
			}
			System.out.println(line);
		}
		

	}

	public void cdm2nc(String filename) {
		NetcdfFile cdmf = null;
		NetcdfFileWriteable ncfile = null;
		try {
			cdmf = NetcdfFile.open(filename);
			ncfile = NetcdfFileWriteable.createNew(filename + ".nc", false);
			ncfile.addDimension("lat", 161);
			ncfile.addDimension("lon", 241);
			ncfile.addDimension("time", 1);
			ncfile.addDimension("ens0", 51);
			String mvstr = "LatLon_161X241-29p75N-100p2E_";

			List<Variable> vars = cdmf.getVariables();
			for (int i = 0; i < vars.size(); i++) {
				Variable var = vars.get(i);
				String name = var.getName().replace("/", "_")
						.replace(mvstr, "");
				if (var.getName().contains("161X241")) {
					String units = var.getUnitsString();
					String descp = var.getDescription();
					System.out.println("Variable name: " + name);
					System.out.println(var.getDimensionsString());
					Variable write_var = ncfile.addVariable(name,
							var.getDataType(), var.getDimensionsString());

					List<Attribute> atts = var.getAttributes();
					for (int j = 0; j < atts.size(); j++) {
						Attribute att = atts.get(j);
						// String name = att.getName().replace("/", "_");
						write_var.addAttribute(att);
					}
				}
			}
			List<Attribute> atts = cdmf.getGlobalAttributes();
			for (int i = 0; i < atts.size(); i++) {
				Attribute att = atts.get(i);
				String name = att.getName().replace("/", "_")
						.replace(mvstr, "");
				ncfile.addGlobalAttribute(name, att.getStringValue());
			}
			ncfile.create();
			for (int i = 0; i < vars.size(); i++) {
				Variable var = vars.get(i);
				String name = var.getName().replace("/", "_")
						.replace(mvstr, "");
				if (var.getName().contains("161X241")) {
					ncfile.write(name, var.read());
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvalidRangeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				cdmf.close();
				ncfile.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}
